from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt
from .tart_bar_name import TartBarName
from .tart_bar_lamp import TartBarLamp
from tart_bar_job_box import TartBarJobBox

class TartBar(QtGui.QWidget):

	def __init__(self, *args, **kw):
		QtGui.QWidget.__init__(self, *args)
		self.setGeometry(0, 0, 780, 55)
#
#		set up the child widgets, of which there are several
#
		self.make_children()
#
#		get index and girl from keywords
#
		self.index = kw["index"]
		girl = kw.get("girl", None)
#
#		populate the widgets
#
		self.set_girl(girl, 0)

	def set_girl(self, girl, index):
		self.girl = girl
		if girl == None:
			self.clear()
			return
		self.index = index
		self.set_name(girl.name)
		self.set_health(girl.health)
		self.set_fatigue(girl.fatigue)
		self.set_morale(girl.morale)
		self.set_morning(girl.jobs[0])
		self.set_afternoon(girl.jobs[1])
		self.set_evening(girl.jobs[2])
		self.set_night(girl.jobs[3])

	def clear(self):
		self.set_name("")
		self.set_health(0)
		self.set_fatigue(0)
		self.set_morale(0)
		self.set_morning("")
		self.set_afternoon("")
		self.set_evening("")
		self.set_night("")

	def make_children(self): # ... which is almost what this game is about!
#
#		basic background image
#
		bg = QtGui.QLabel(self) 
		bg.setGeometry(0, 0, 780, 55)
		path = "resources/tart_bar.png"
		bg.setPixmap(QtGui.QPixmap(path))
		self.bar = bg
#
#		not sure if it's easier here to have two images
#		or just one and swap the pixmaps...
#
		bg = QtGui.QLabel(self) 
		bg.setGeometry(-1, 2, 780, 55)
		path = "resources/tart_bar_red.png"
		bg.setPixmap(QtGui.QPixmap(path))
		self.redbar = bg
		self.redbar.hide()
#
#		the box that shows the girl's name
#		has some signals that need to be propagated
#
		name_box = TartBarName(self)
		name_box.move(25,5)
		self.name_box = name_box
		name_box.clicked.connect(self.on_click)
		name_box.doubleclicked.connect(self.on_2click)
#
#		lamp indicators for health, fatigue and morale
#
		health_lamp = TartBarLamp(self)
		health_lamp.move(260,5)
		self.health = health_lamp
#
#		fatigue - currently the inverse of tiredness
#
		fatigue_lamp = TartBarLamp(self)
		fatigue_lamp.move(302,5)
		self.fatigue = fatigue_lamp 
#
#		and morale which is just an alias for happiness atm
#
		morale_lamp = TartBarLamp(self)
		morale_lamp.move(344,5)
		self.morale = morale_lamp
#
#		job boxes - morning
#
#		note that we set the name of the column and the index
#		into the jobs array, as well as assigning a slot for the
#		job_menu signal
#
		jb = TartBarJobBox(self)
		jb.move(386,5)
		jb.period_name = "morning"
		jb.period_index = 0
		jb.job_menu.connect(self.job_box_cb)
		self.morning = jb
#
#		arrternoon, suur!
#
		jb = TartBarJobBox(self)
		jb.move(479,5)
		jb.period_name = "afternoon"
		jb.period_index = 1
		jb.job_menu.connect(self.job_box_cb)
		self.afternoon = jb
#
#		goot evenink!
#
		jb = TartBarJobBox(self)
		jb.move(572,5)
		jb.period_name = "evening"
		jb.period_index = 2
		jb.job_menu.connect(self.job_box_cb)
		self.evening = jb
#
#		and to all a good night!
#
		jb = TartBarJobBox(self)
		jb.move(665,5)
		jb.period_name = "night"
		jb.period_index = 3
		jb.job_menu.connect(self.job_box_cb)
		self.night = jb

#
#	forward the job menu signal up the stack
#	add in a reference to the row (self) as well
#
	job_box_clicked = QtCore.pyqtSignal(object, object)
	def job_box_cb(self, box):
		self.job_box_clicked.emit(self, box)

#
#	func to change the highlight status of the bar
#
	def highlight(self, flag=None):
		if flag == None:
			flag = self.redbar.isHidden()
		if flag:
			self.redbar.show()
		else:
			self.redbar.hide()

#
#	next, we have a metric ton of set_ functions
#
	def set_name(self, s):
		self.name_box.set_text(s)

#
#	these are the lamp fields
#	we need to make sure values are capped at 100
#	or else we run out of gradient which does not look good
#
	def set_health(self, pc):
		if pc > 100: pc = 100
		self.health.set_percent(pc)
	def set_fatigue(self, pc):
		if pc > 100: pc = 100
		self.fatigue.set_percent(pc)
	def set_morale(self, pc):
		if pc > 100: pc = 100
		self.morale.set_percent(pc)
#
#	set the job slots. default to "Rest"
#
	def set_morning(self, job):
		if job == None: job = "Rest"
		self.morning.set_text(job)
	def set_afternoon(self, job):
		if job == None: job = "Rest"
		self.afternoon.set_text(job)
	def set_evening(self, job):
		if job == None: job = "Rest"
		self.evening.set_text(job)
	def set_night(self, job):
		if job == None: job = "Rest"
		self.night.set_text(job)

#
#	as well as catching clicks from children
#	raise them ourselves
#
#	this probably makes most of the child handlers
#	unnecessary
#
	def mousePressEvent(self, e):
		self.clicked.emit(self)

#
#	signals for single and double clicks
#
#	I'm detecting these in the children,
#	since cicking on job boxes will open a menu
#
#	I'm also going to explicitly pass the girl and
#	index up from this point
#
	clicked = QtCore.pyqtSignal(object)
	doubleclicked = QtCore.pyqtSignal(object)

#
#	I could link the signals to the child widget signals
#	but then sender() would report as the child
#	and I'd need to propagate girl and index info to all the
#	child widgets. This is less work, I feel
#
	def on_click(self):
		self.clicked.emit(self)
	def on_2click(self):
		self.doubleclicked.emit(self)

if __name__ == "__main__":
	import sys
	from collections import namedtuple

#
#	using namedtuple to generate a quick mock class for Girl
#
	Girly = namedtuple('Girly', 'name health fatigue morale jobs')

#
#	create the app
#
	app = QtGui.QApplication(sys.argv)

#
#	use the wallpaper as the top level widget
#
	top = QtGui.QLabel()
	top.setGeometry(0, 0, 830, 150)
	path = "resources/wood.jpg"
	top.setPixmap(QtGui.QPixmap(path))

#
#	a "normal" bar
#
	bar1 = TartBar(top,
		index = 0,
		girl = Girly(
			name    = "Clarissa Verylongname",
			health  = 30,
			fatigue = 60,
			morale  = 90,
			jobs	= [
				"Sleep",
				"Cleaning",
				"Whoring",
				"Cabaret"
			]
		)
	)
	bar1.move(20,20)

#
#	one more so we can compare highlight state
#
	bar2 = TartBar(top,
		index = 1,
		girl = Girly(
			name    = "Flossy Mossy",
			health  = 100,
			fatigue = 50,
			morale  = 10,
			jobs	= [
				"Assistant",
				"Assistant",
				"Assistant",
				"Assistant",
			]
		)
	)
	bar2.move(20,75)
	bar2.highlight()

#
#	I was going to pass shift status up the event chain
#	but this is better. keyboardModifiers reflects the state
#	of the keyboard at the time of the event in any case
#	so this is just as accurate and simplifies the class
#
#	not that I'm doing anything with the modifier state here
#	but I'll want to use it for multiple selection
#
	def modstr():
		str = ""
		mods = QtGui.QApplication.keyboardModifiers()
		if mods & QtCore.Qt.ControlModifier:
			str += "ctrl-"
		if mods & QtCore.Qt.ShiftModifier:
			str += "shift-"
		return str

	def click1(bar):
		print "single {}click on index {} : {}".format(
			modstr(), bar.index, bar.girl.name
		)

	def click2(bar):
		print "double {}click on index {} : {}".format(
			modstr(), bar.index, bar.girl.name
		)
		bar.highlight()
	bar1.clicked.connect(click1)
	bar2.clicked.connect(click1)
	bar1.doubleclicked.connect(click2)
	bar2.doubleclicked.connect(click2)

	top.show()
	sys.exit(app.exec_())


